---
import { NavBarWrapper } from '../components/layouts';
import { ChatWidget } from '../components/chat';
import { BackToTopButton } from '../components/ui';
import {
  FAVICON_PATHS,
  VIEWPORT_ZOOM_ALLOWED,
  PERSON_SCHEMA,
  SITE_BASE_URL,
  SITE_DOMAIN,
  SITE_NAME_EN,
  DEFAULT_SOCIAL_IMAGE,
  OG_IMAGE_DIMENSIONS,
  GEO_REGION,
  GEO_PLACENAME_EN,
  GEO_POSITION,
  GEO_ICBM,
  TWITTER_HANDLE,
  LANG_STORAGE_KEY,
  THEME_STORAGE_KEY,
  LOGIN_STATE_KEY,
  STYLE_PATHS
} from '../constants';
import { isProduction } from '../utils/env';
import '../styles/theme.css';

interface OpenGraphProps {
  title?: string;
  description?: string;
  url?: string;
  type?: string;
  image?: string;
  site_name?: string;
  imageWidth?: string;
  imageHeight?: string;
  imageAlt?: string;
  imageType?: string;
  secureImageUrl?: string;
}

interface TwitterCardProps {
  card?: string;
  title?: string;
  description?: string;
  image?: string;
  imageAlt?: string;
  site?: string;
  creator?: string;
  url?: string;
  domain?: string;
}

export interface BaseLayoutProps {
  lang?: string;
  title?: string;
  titleZh?: string;
  titleEn?: string;
  description?: string;
  viewport?: string;
  canonical?: string;
  personSchemaJson?: string;
  extraStyles?: Array<string | URL>;
  preloadStyles?: Array<string | URL>;
  extraScripts?: string[];
  showNav?: boolean;
  showFooter?: boolean;
  showChatWidget?: boolean;
  bodyClass?: string;
  mainClass?: string;
  bodyAttrs?: Record<string, unknown>;
  mainAttrs?: Record<string, unknown>;
  og?: OpenGraphProps;
  twitter?: TwitterCardProps;
  includeGeo?: boolean;
  metaRobots?: string;
  metaLanguage?: string;
  metaAuthor?: string;
}

const {
  lang: langProp,
  title = '',
  titleZh = '',
  titleEn = '',
  description = '',
  viewport = VIEWPORT_ZOOM_ALLOWED,
  canonical = '',
  personSchemaJson = JSON.stringify(PERSON_SCHEMA),
  extraStyles = [],
  preloadStyles = [],
  extraScripts = [],
  showNav = true,
  showFooter = false,
  showChatWidget = true,
  bodyClass = '',
  mainClass = 'c-main-content',
  bodyAttrs = {},
  mainAttrs = {},
  og = {},
  twitter = {},
  includeGeo = true,
  metaRobots = 'index, follow',
  metaLanguage = '',
  metaAuthor = ''
}: BaseLayoutProps = Astro.props;

if (showChatWidget) {
  preloadStyles.push(STYLE_PATHS.CHAT_WIDGET);
  extraStyles.push(STYLE_PATHS.CHAT_WIDGET);
}

const lang = langProp || 'zh-CN';
const initialLang = lang;
const effectiveTitleZh = titleZh || title;
const effectiveTitleEn = titleEn || title;
const initialTitle = initialLang.startsWith('zh') ? effectiveTitleZh : effectiveTitleEn;

const IS_PROD = isProduction();
const jsonLD = personSchemaJson;
const ogDefaults = {
  title,
  description,
  url: canonical,
  type: 'website',
  image: `${SITE_BASE_URL}${DEFAULT_SOCIAL_IMAGE}`,
  site_name: SITE_NAME_EN,
  imageWidth: OG_IMAGE_DIMENSIONS.WIDTH,
  imageHeight: OG_IMAGE_DIMENSIONS.HEIGHT,
  imageAlt: '',
  imageType: 'image/jpeg',
  secureImageUrl: `${SITE_BASE_URL}${DEFAULT_SOCIAL_IMAGE}`
};
const twitterDefaults = {
  card: 'summary_large_image',
  title,
  description,
  image: ogDefaults.image,
  imageAlt: '',
  site: TWITTER_HANDLE,
  creator: TWITTER_HANDLE,
  url: canonical,
  domain: SITE_DOMAIN
};
const ogProps = { ...ogDefaults, ...og };
const twitterProps = { ...twitterDefaults, ...twitter };
---

<html lang={lang}>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content={viewport} />
    <script
      is:inline
      src="/js/base-layout-init.js"
      data-theme-key={THEME_STORAGE_KEY}
      data-lang-key={LANG_STORAGE_KEY}
      data-login-key={LOGIN_STATE_KEY}
      data-title-zh={effectiveTitleZh}
      data-title-en={effectiveTitleEn}
      data-is-prod={IS_PROD}></script>
    {initialTitle && <title>{initialTitle}</title>}
    {description && <meta name="description" content={description} />}
    <link rel="shortcut icon" type="image/x-icon" href={FAVICON_PATHS.ICO} />
    <link rel="icon" type="image/png" href={FAVICON_PATHS.PNG} />
    <link rel="apple-touch-icon" href={FAVICON_PATHS.SMALL} />
    <link rel="canonical" href={canonical} />
    {metaRobots && <meta name="robots" content={metaRobots} />}
    {metaAuthor && <meta name="author" content={metaAuthor} />}
    <meta name="language" content={metaLanguage || lang} />
    {
      includeGeo && (
        <Fragment>
          <meta name="geo.region" content={GEO_REGION} />
          <meta name="geo.placename" content={GEO_PLACENAME_EN} />
          <meta name="geo.position" content={GEO_POSITION} />
          <meta name="ICBM" content={GEO_ICBM} />
        </Fragment>
      )
    }
    {ogProps.title && <meta property="og:title" content={ogProps.title} />}
    {ogProps.description && <meta property="og:description" content={ogProps.description} />}
    {ogProps.type && <meta property="og:type" content={ogProps.type} />}
    {ogProps.url && <meta property="og:url" content={ogProps.url} />}
    {ogProps.image && <meta property="og:image" content={ogProps.image} />}
    {ogProps.site_name && <meta property="og:site_name" content={ogProps.site_name} />}
    {ogProps.imageWidth && <meta property="og:image:width" content={ogProps.imageWidth} />}
    {ogProps.imageHeight && <meta property="og:image:height" content={ogProps.imageHeight} />}
    {ogProps.imageAlt && <meta property="og:image:alt" content={ogProps.imageAlt} />}
    {ogProps.imageType && <meta property="og:image:type" content={ogProps.imageType} />}
    {
      ogProps.secureImageUrl && (
        <meta property="og:image:secure_url" content={ogProps.secureImageUrl} />
      )
    }
    {twitterProps.card && <meta name="twitter:card" content={twitterProps.card} />}
    {twitterProps.title && <meta name="twitter:title" content={twitterProps.title} />}
    {
      twitterProps.description && (
        <meta name="twitter:description" content={twitterProps.description} />
      )
    }
    {twitterProps.image && <meta name="twitter:image" content={twitterProps.image} />}
    {twitterProps.imageAlt && <meta name="twitter:image:alt" content={twitterProps.imageAlt} />}
    {twitterProps.site && <meta name="twitter:site" content={twitterProps.site} />}
    {twitterProps.creator && <meta name="twitter:creator" content={twitterProps.creator} />}
    {twitterProps.url && <meta name="twitter:url" content={twitterProps.url} />}
    {twitterProps.domain && <meta name="twitter:domain" content={twitterProps.domain} />}
    <script type="application/ld+json" is:inline set:html={jsonLD} />
    {
      preloadStyles
        .filter(Boolean)
        .map((href: string | URL) => <link rel="preload" href={href} as="style" />)
    }
    {extraStyles.filter(Boolean).map((href: string | URL) => <link rel="stylesheet" href={href} />)}
    <slot name="head" />
  </head>
  <body class={bodyClass} {...bodyAttrs}>
    {showNav && <NavBarWrapper initialLang={initialLang} showNav={showNav} client:load />}
    <main class={mainClass} {...mainAttrs}>
      <slot />
    </main>
    {showChatWidget && <ChatWidget client:visible />}
    <BackToTopButton client:load />
    <slot name="bodyEnd" />
    {showFooter && <slot name="footer" />}
    {extraScripts.filter(Boolean).map((src: string) => <script is:inline defer src={src} />)}
  </body>
</html>
